#pragma once
//----------------------------------------------------------------------------------------------------------------
//			Filename:		Lambertian.h
//			  Author:		Adrian De Barro
//			    Date:		12/08/2015
//----------------------------------------------------------------------------------------------------------------
//			  Status: READY
//----------------------------------------------------------------------------------------------------------------
#include "..\CoreClasses\RGBObject\RGBColor.h"
#include "BRDF.h"
#include "..\CoreClasses\UtilClasses\Common.h"
#include "..\Material\Textures\Texture.h"
#include "..\CoreClasses\GeometricObjects\Triangle.h"
#include "..\CoreClasses\Point\Point2D\Point2D.h"

namespace Engine
{
	//----------------------------------------------------------------------------------------------------------------
	//			Class Name: PrimitiveBvhRepresentation
	//		   Description: Concrete implementation of BRDF abstract class, 
	//						implements the lambertian function for lambertian surfaces
	//----------------------------------------------------------------------------------------------------------------
	//			    Status: REFACTORING
	//----------------------------------------------------------------------------------------------------------------
	class Lambertian : public Engine::BRDF
	{
	public:
			//----------------------------------------------------------------------------------------------------------------
			//		 Method Name: CONSTRUCTOR
			//		Return Value: VOID
			//		  Parameters: VOID
			//			  Status: READY
			//----------------------------------------------------------------------------------------------------------------
			Lambertian() :m_kd(0), m_cd(0)
			{}
			//----------------------------------------------------------------------------------------------------------------
			//		 Method Name: CONSTRUCTOR
			//		Return Value: VOID
			//		  Parameters: D
			//			  Status: READY
			//----------------------------------------------------------------------------------------------------------------
			Lambertian(float p_kd, RGBColor p_cd) : m_kd(p_kd), m_cd(p_cd)
			{}
			//----------------------------------------------------------------------------------------------------------------
			//		 Method Name: CONSTRUCTOR
			//		Return Value: VOID
			//		  Parameters: Diffuse Constant, Surface Color
			//			  Status: READY
			//----------------------------------------------------------------------------------------------------------------
			Lambertian(float p_kD, Texture* p_currentTexture) : m_usedTexture(p_currentTexture), m_cd(0), m_kd(p_kD)
			{}
			//----------------------------------------------------------------------------------------------------------------
			//		 Method Name: f
			//		Return Value: RGBColor
			//		  Parameters: Collision Details, input direction, output direction, boolean contains texture
			//			  Status: READY
			//----------------------------------------------------------------------------------------------------------------
			virtual RGBColor f(ShadeRec& sr, Point3D wi, Point3D w0, RGBColor& p_colorAtPoint, bool p_containsTexture = false)
			{
				if (p_containsTexture)
				{
					Triangle* currentTriangle = (Triangle*)sr.m_hitTriangle;
					ShadeRec testInterm;
					Point2D barCoor = currentTriangle->CalcBarycentric(sr.ray, testInterm);
					RGBColor textureBaseColor = currentTriangle->GetMaterial()->GetColor(barCoor.x, barCoor.y);
					p_colorAtPoint = textureBaseColor;
					return ( textureBaseColor*  m_kd * 1 / PI_NUM);
				}
				else
				{
			
					float x = 0, y = 0;
					return (m_usedTexture->GetColor(x,y) *  m_kd * 1 / PI_NUM);
				}
			}
			//----------------------------------------------------------------------------------------------------------------
			//		 Method Name: sampleF
			//		Return Value: RGBColor
			//		  Parameters: Collision Details, input direction, output direction
			//			  Status: READY
			//----------------------------------------------------------------------------------------------------------------
			virtual RGBColor sampleF(ShadeRec& sr, Point3D wi, Point3D w0)
			{
				return RGBColor(0);
			}
			//----------------------------------------------------------------------------------------------------------------
			//		 Method Name: rho
			//		Return Value: RGBColor
			//		  Parameters: Collision Details, output direction
			//			  Status: READY
			//----------------------------------------------------------------------------------------------------------------
			virtual RGBColor rho(ShadeRec& sr, Point3D w0)
			{
				return (m_cd * m_kd );
			}
			//----------------------------------------------------------------------------------------------------------------
			//		 Method Name: SetColor
			//		Return Value: RGBColor
			//		  Parameters: RGBColor 
			//			  Status: READY
			//----------------------------------------------------------------------------------------------------------------
			void SetColor(RGBColor p_color)
			{
				m_cd = p_color;
			}
			//----------------------------------------------------------------------------------------------------------------
			//		 Method Name: GetColor
			//		Return Value: RGBColor
			//		  Parameters: VOID
			//			  Status: READY
			//----------------------------------------------------------------------------------------------------------------
			RGBColor GetColor()
			{
				return m_cd;
			}
			//----------------------------------------------------------------------------------------------------------------
			//		 Method Name: GetKd
			//		Return Value: float
			//		  Parameters: VOID
			//			  Status: READY
			//----------------------------------------------------------------------------------------------------------------
			float GetKd()
			{
				return m_kd;
			}
			//----------------------------------------------------------------------------------------------------------------
			//		 Method Name: SetKd
			//		Return Value: VOID
			//		  Parameters: float diffuse constant
			//			  Status: READY
			//----------------------------------------------------------------------------------------------------------------
			void SetKd(float kD)
			{
				m_kd = kD;
			}

		private:
			float m_kd;
			RGBColor m_cd;
			Texture* m_usedTexture;
	};
	//----------------------------------------------------------------------------------------------------------------
}
//----------------------------------------------------------------------------------------------------------------